home *** CD-ROM | disk | FTP | other *** search
- /*
- * BLOTCH.C -- Layout Plugin Shader
- * Stick a colored spot on a surface
- *
- * by Allen Hastings and Arnie Cachelin
- * revised by Stuart Ferguson
- * last revision 6/15/95
- */
- #include <splug.h>
- #include <moni.h>
- #include <lwran.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
-
-
-
- /*
- * HANDLER -- Instance Methods
- *
- * An instance is a particular set of user-set options for a plug-in
- * operation. The options for a blotch are the color tint, the center
- * and radius, and a number for the softness of the blotch edges.
- */
- typedef struct st_Blotch {
- double color[3];
- double center[3];
- double radius;
- double softness;
- double r2, piOverR;
- } Blotch;
-
-
- /*
- * The create function allocates a blotch struct and returns its
- * pointer as the instance. Note that "Blotch *" is used throughout
- * instead of "LWInstance". This works since a LWInstance type is
- * a generic pointer and can be safely replaced with any specific
- * pointer type. Instance variables are initialized to some default
- * values.
- */
- XCALL_(static LWInstance)
- Create (
- LWError *err)
- {
- Blotch *inst;
-
- XCALL_INIT;
-
- inst = malloc (sizeof (Blotch));
- if (!inst)
- return NULL;
-
- inst->color[0] = 0.4;
- inst->color[1] = 0.0;
- inst->color[2] = 0.8;
-
- inst->center[0] = inst->center[1] = inst->center[2] = 0.0;
- inst->radius = 1.0;
- inst->softness = 0.5;
-
- return inst;
- }
-
-
- /*
- * Destroy frees the blotch instance memory.
- */
- XCALL_(static void)
- Destroy (
- Blotch *inst)
- {
- XCALL_INIT;
- free (inst);
- }
-
-
- /*
- * Copy simply moves the data settings from one blotch struct to
- * another.
- */
- XCALL_(static LWError)
- Copy (
- Blotch *from,
- Blotch *to)
- {
- XCALL_INIT;
-
- *to = *from;
- return (NULL);
- }
-
-
- /*
- * Load and save.
- */
- XCALL_(static LWError)
- Load (
- Blotch *inst,
- const LWLoadState *lState)
- {
- XCALL_INIT;
- return (NULL);
- }
-
- XCALL_(LWError)
- Save (
- Blotch *inst,
- const LWSaveState *sState)
- {
- XCALL_INIT;
- return (NULL);
- }
-
-
- /*
- * INIT and CLEANUP
- *
- * The host calls these callbacks for each shader instance just before
- * and just after rendering. This is the place to do any precalculation
- * to speed up the rendering of an instance.
- */
- XCALL_(static LWError)
- Init (
- Blotch *inst)
- {
- XCALL_INIT;
-
- inst->r2 = inst->radius * inst->radius;
- inst->piOverR = 3.1416 / inst->radius;
-
- return (NULL);
- }
-
- XCALL_(static void)
- Cleanup (
- Blotch *inst)
- {
- XCALL_INIT;
- }
-
-
- /*
- * NEWTIME
- *
- * The host calls this callback whenever a different timestep will be
- * being rendered. It is called once at the start of a frame and more
- * times during the frame if the frame requires includes multiple
- * times (like in motion blur or field-rendering).
- */
- XCALL_(static LWError)
- NewTime (
- Blotch *inst,
- LWFrame f,
- LWTime t)
- {
- XCALL_INIT;
- return (NULL);
- }
-
-
- /*
- * FLAGS
- *
- * The host calls the flags function to find out some information about
- * this shader instance. Since all blotches will alter the color of
- * a surface but nothing else, the shader color bit is returned.
- */
- XCALL_(static unsigned int)
- Flags (
- Blotch *inst)
- {
- XCALL_INIT;
- return (LWSHF_COLOR);
- }
-
-
- /*
- * EVALUATE
- *
- * This is the guts of the shader. It is called for each spot that needs
- * to be colored with this shader in the final image. The shaderAccess
- * struct contains info about the spot and some values may be modified
- * by the shader according to what bits were returned in the flags
- * callback.
- *
- * The blotch shader will compute the distance of this point to the center
- * of the blotch and blend some of the blotch color with the color already
- * computed for that spot.
- */
- XCALL_(static void)
- Evaluate (
- Blotch *inst,
- ShaderAccess *sa)
- {
- double d, r2, a;
- int i;
-
- XCALL_INIT;
-
- /*
- * Compute the distance from the center of the blotch to the spot
- * in object coordinates. Exit early if the spot is clearly
- * outside the blotch radius.
- */
- r2 = 0;
- for (i = 0; i < 3; i++) {
- d = sa->oPos[i] - inst->center[i];
- d = d * d;
- if (d > inst->r2)
- return;
-
- r2 += d;
- }
- if (r2 > inst->r2)
- return;
-
- d = sqrt (r2);
-
- /*
- * Using the distance in 'd', compute where this spot falls in
- * blotch's soft edge. The blotch is given by a cosine density
- * function scaled by the softness factor. Where the density is
- * greater than 1.0, it clips.
- */
- d = cos (d * inst->piOverR) * inst->softness;
- if (d > 1.0)
- d = 1.0;
-
- /*
- * Finally, blend the blotch color into the existing color using
- * the computed density.
- */
- a = 1.0 - d;
- for (i = 0; i < 3; i++)
- sa->color[i] = sa->color[i] * a + inst->color[i] * d;
- }
-
-
-
- /*
- * ACTIVATE
- *
- * The activation function for shader handlers just fills in the shader
- * handler fields with callbacks for this blotch shader.
- */
- XCALL_(static int)
- BlotchActivate (
- long version,
- GlobalFunc *global,
- ShaderHandler *local,
- void *serverData)
- {
- XCALL_INIT;
- if (version != 1)
- return (AFUNC_BADVERSION);
-
- local->inst.create = Create;
- local->inst.destroy = Destroy;
- local->inst.load = Load;
- local->inst.save = Save;
- local->inst.copy = Copy;
-
- local->init = Init;
- local->cleanup = Cleanup;
- local->newTime = NewTime;
- local->evaluate = Evaluate;
- local->flags = Flags;
-
- return (AFUNC_OK);
- }
-
-
-
- /*
- * INTERFACE
- *
- * The interface function for a shader is actually the activation function
- * of the ShaderInterface class server for this instance type. The instance
- * to be edited is passed as the local data pointer to the interface
- * activation function. This function allows the user to edit the instance.
- */
- XCALL_(static int)
- Interface (
- long version,
- GlobalFunc *global,
- Blotch *inst,
- void *serverData)
- {
- MessageFuncs *msg;
- char s1[100], s2[100];
-
- XCALL_INIT;
- if (version != 1)
- return (AFUNC_BADVERSION);
-
- msg = (*global) ("Info Messages", GFUSE_TRANSIENT);
- if (!msg)
- return (AFUNC_BADGLOBAL);
-
- /*
- * Since a full user interface is beyond the scope of this sample
- * plug-in, this function will just display the current settings
- * of the shader.
- */
- sprintf (s1, "BLOTCH: center (%f, %f, %f), radius %f",
- inst->center[0], inst->center[1], inst->center[2],
- inst->radius);
- sprintf (s2, "color (%5.3f, %5.3f, %5.3f), softness %f",
- inst->color[0], inst->color[1], inst->color[2],
- inst->softness);
- (*msg->info) (s1, s2);
-
- return (AFUNC_OK);
- }
-
-
-
- /*
- * This plug-in module contains two servers -- one for the shader handler
- * and one for the interface. The blotch instance will be passed to
- * this interface server since it has the same name as the handler. These
- * servers do not have to be in the same module if a render-only shader
- * plug-in is required.
- */
- ServerRecord ServerDesc[] = {
- { "ShaderHandler", "Demo_Blotch", BlotchActivate },
- { "ShaderInterface", "Demo_Blotch", Interface },
- { NULL }
- };
-